package com.global.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;

import org.compass.annotations.SearchableId;
import org.hibernate.annotations.Type;

/**
 * 
 * @author zhanglinye
 *
 */
@Entity
@org.hibernate.annotations.Entity(dynamicUpdate=true)
@Table(name = "ZLY_ST_BSC_QPDF", uniqueConstraints = {
		@UniqueConstraint(columnNames = {"DSO_ID", "NAME"}),
		@UniqueConstraint(columnNames = {"DSO_ID", "PARAMETERINDEX"})})
@SequenceGenerator(name="ZLY_ST_BSC_QPDF_ID_GENERATOR", sequenceName="ZLY_ST_BSC_QPDF_ID_SEQ", initialValue=1000, allocationSize=1)	
@NamedQueries({
        @NamedQuery(
                name = "findQueryParameterDefinitionByDataSourceXAndParameterName",
                query = "select q from QueryParameterDefinition q where q.dataSourceX.id = :dataSourceXId and upper(q.name) = upper(:parameterName) "
        ),
        @NamedQuery(
                name = "findQueryParameterDefinitionByDataSourceX",
                query = "select q from QueryParameterDefinition q where q.dataSourceX.id = :dataSourceXId order by q.displayIndex "
        ),
        @NamedQuery(
                name = "findQueryParameterDefinitionsByDataSourceXAndFilter",
                query = "select q from QueryParameterDefinition q where q.dataSourceX.id = :dataSourceXId And q.filter = :isFilter order by q.parameterIndex "
        )
        
})
public class QueryParameterDefinition extends BaseObject implements Serializable {

	private static final long serialVersionUID = -3509997220679503723L;
	
	private Long id;
	private String name;
	private String javaDataType;
	private String defaultValue;
	private int parameterIndex;
	private int displayIndex;
	
	private DataSourceX dataSourceX;
	
	private boolean filter;
	
	private boolean canDisplay;
	private boolean canEmpty;
	
    /**
     * 定义操作人、操作时间
     */
    private Who who;
    
	@Id	
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ZLY_ST_BSC_QPDF_ID_GENERATOR")
	@SearchableId
	public Long getId() {
		return this.id;
	}
	public void setId(Long id) {
		this.id = id;
	}	
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	public String getJavaDataType() {
		return javaDataType;
	}	
	public void setJavaDataType(String javaDataType) {
		this.javaDataType = javaDataType;
	}
	
	public String getDefaultValue() {
		return defaultValue;
	}
	public void setDefaultValue(String defaultValue) {
		this.defaultValue = defaultValue;
	}
	
	/**
	 * 获取参数在SQL查询语句中的顺序
	 * @return
	 */
	public int getParameterIndex() {
		return parameterIndex;
	}
	/**
	 * 设置参数在SQL查询语句中的顺序
	 * @param parameterIndex 从1开始
	 */
	public void setParameterIndex(int parameterIndex) {
		this.parameterIndex = parameterIndex;
	}
	
	
	public int getDisplayIndex() {
		return displayIndex;
	}
	public void setDisplayIndex(int displayIndex) {
		this.displayIndex = displayIndex;
	}
	
	/**
	 * {@inheritDoc}
	 */
	public Who getWho() {
		return who;
	}
	/**
	 * {@inheritDoc}
	 */
	public void setWho(Who who) {
		this.who = who;
	}
	
	/**
	 * 返回数据源
	 * @return DataSourceX
	 */
	//bi-directional many-to-one association to DataSouceX
    @ManyToOne
	@JoinColumn(name="DSO_ID", nullable=false)
	public DataSourceX getDataSourceX() {
		return this.dataSourceX;
	}
	public void setDataSourceX(DataSourceX dataSourceX) {
		this.dataSourceX = dataSourceX;
	}
	
	/**
	 * 参数是否显示
	 * @return true表示参数需要显示出来
	 */
	@Column(nullable=false, length=1)
	@Type(type="yes_no")
	public boolean isCanDisplay() {
		return canDisplay;
	}
	public void setCanDisplay(boolean canDisplay) {
		this.canDisplay = canDisplay;
	}
	
	/**
	 * 参数是否允许为空
	 * @return false表示不允许为空
	 */
	@Column(nullable=false, length=1)
	@Type(type="yes_no")
	public boolean isCanEmpty() {
		return canEmpty;
	}
	public void setCanEmpty(boolean canEmpty) {
		this.canEmpty = canEmpty;
	}
	
	/**
	 * 是否为过滤数据参数，过滤性参数可以select语句的where条件中实现  a = ? 或者 a=a 或者 a is null 或者 a is not null 功能
	 * <br/> 固定参数即必须参数，只能实现 在where语句事前定义的语句
	 * @return true 表示为过滤性参数，即参数名称从select语句中获得，false 表示为确认数据范围的参数
	 */
	@Column(nullable=false, length=1)
	@Type(type="yes_no")
	public boolean isFilter() {
		return filter;
	}
	/**
	 * 设置参数是否为固定参数
	 * @param filter false表示为固定参数，true表示为过滤类型参数，即从select 后面获取到的栏位
	 */
	public void setFilter(boolean filter) {
		this.filter = filter;
	}
	
	/**
	 * 是否为固定参数
	 * @return true 表示为固定参数
	 */
	@Transient
	public boolean isFixed() {
		return !filter;
	}
	@Override
	public String toString() {
		return "QueryParameterDefinition [name=" + name + ", javaDataType="
				+ javaDataType + ", defaultValue=" + defaultValue
				+ ", parameterIndex=" + parameterIndex + ", displayIndex="
				+ displayIndex + ", dataSourceX=" + (dataSourceX==null ? "" : dataSourceX.getDescription())
				+ ", isFilter= " + filter+ ", isNamedParameter= " + !filter
				+ ", isCanDisplay=" + canDisplay + ", isCanEmpty=" + canEmpty + "]";
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((dataSourceX == null) ? 0 : dataSourceX.hashCode());
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		
		QueryParameterDefinition other = (QueryParameterDefinition) obj;
		if (dataSourceX == null) {
			if (other.dataSourceX != null)
				return false;
		} else if (!dataSourceX.equals(other.dataSourceX))
			return false;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equalsIgnoreCase(other.name))
			return false;
		
		return true;
	}	
}
